home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / c / dir.c < prev    next >
C/C++ Source or Header  |  1996-09-13  |  5KB  |  297 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: dir.c,v 1.6 1996/09/13 17:52:10 digulla Exp $
  4.     $Log: dir.c,v $
  5.     Revision 1.6  1996/09/13 17:52:10  digulla
  6.     Use IPTR
  7.  
  8.     Revision 1.5  1996/08/01 17:40:44  digulla
  9.     Added standard header for all files
  10.  
  11.     Desc:
  12.     Lang:
  13. */
  14. #include <exec/memory.h>
  15. #include <clib/exec_protos.h>
  16. #include <dos/dos.h>
  17. #include <dos/exall.h>
  18. #include <dos/datetime.h>
  19. #include <clib/dos_protos.h>
  20. #include <clib/utility_protos.h>
  21. #include <utility/tagitem.h>
  22. #include <utility/utility.h>
  23. #include <stdlib.h>
  24.  
  25. /* Don't define symbols before the entry point. */
  26. extern struct ExecBase *SysBase;
  27. extern struct DosLibrary *DOSBase;
  28. extern struct UtilityBase *UtilityBase;
  29. extern const char dosname[];
  30. static LONG tinymain(void);
  31.  
  32. __AROS_LH0(LONG,entry,struct ExecBase *,sysbase,,)
  33. {
  34.     __AROS_FUNC_INIT
  35.     LONG error=RETURN_FAIL;
  36.  
  37.     SysBase=sysbase;
  38.     DOSBase=(struct DosLibrary *)OpenLibrary((STRPTR)dosname,39);
  39.     UtilityBase=(struct UtilityBase *)OpenLibrary(UTILITYNAME,39);
  40.     if(DOSBase!=NULL && UtilityBase != NULL)
  41.     {
  42.     error=tinymain();
  43.     CloseLibrary((struct Library *)DOSBase);
  44.     }
  45.     return error;
  46.     __AROS_FUNC_EXIT
  47. }
  48.  
  49. struct ExecBase *SysBase;
  50. struct DosLibrary *DOSBase;
  51. struct UtilityBase *UtilityBase;
  52. const char dosname[]="dos.library";
  53.  
  54. struct table
  55. {
  56.     char ** entries;
  57.     int     num, max;
  58. };
  59.  
  60. char ** files;
  61. int num_files, max_files;
  62. char ** dirs;
  63. int num_dirs, max_dirs;
  64.  
  65. static int AddEntry (struct table * table, char * entry)
  66. {
  67.     char * dup;
  68.     int len;
  69.  
  70.     if (table->num == table->max)
  71.     {
  72.     int new_max = table->max + 128;
  73.     char ** new_entries;
  74.  
  75.     new_entries = AllocVec (sizeof(char *)*new_max, MEMF_ANY);
  76.  
  77.     if (!new_entries)
  78.         return 0;
  79.  
  80.     if (table->num)
  81.     {
  82.         CopyMemQuick (table->entries, new_entries, sizeof(char *)* table->num);
  83.         FreeVec (table->entries);
  84.     }
  85.  
  86.     table->entries = new_entries;
  87.     table->max = new_max;
  88.     }
  89.  
  90.     len = strlen (entry) + 1;
  91.  
  92.     if (!(dup = AllocVec (len, MEMF_ANY)) )
  93.     return 0;
  94.  
  95.     CopyMem ((char *)entry, dup, len);
  96.  
  97.     table->entries[table->num ++] = dup;
  98.     return 1;
  99. }
  100.  
  101. static int compare_strings (const void * s1, const void * s2)
  102. {
  103.     return Stricmp (*(char **)s1, *(char **)s2);
  104. }
  105.  
  106. int indent = 0;
  107. static void showline (char * fmt, LONG args[])
  108. {
  109.     int t;
  110.  
  111.     for (t=0; t<indent; t++)
  112.     VPrintf ("    ", NULL);
  113.  
  114.     VPrintf (fmt, args);
  115. }
  116.  
  117. struct
  118. {
  119.     char * dir;
  120.     char * opt;
  121.     ULONG all;
  122. } args = {
  123.     NULL,
  124.     NULL,
  125.     0
  126. };
  127. char path[1024];
  128.  
  129. static LONG do_dir (void)
  130. {
  131.     BPTR dir;
  132.     LONG loop;
  133.     struct ExAllControl *eac;
  134.     struct ExAllData *ead;
  135.     static UBYTE buffer[4096];
  136.     LONG error=0;
  137.     struct table dirs, files;
  138.  
  139.     dirs.entries = files.entries = NULL;
  140.     dirs.max = files.max = 0;
  141.     dirs.num = files.num = 0;
  142.  
  143.     dir=Lock(path,SHARED_LOCK);
  144.     if(dir)
  145.     {
  146.     eac=AllocDosObject(DOS_EXALLCONTROL,NULL);
  147.     if(eac!=NULL)
  148.     {
  149.         int t;
  150.         IPTR argv[3];
  151.  
  152.         eac->eac_LastKey=0;
  153.         do
  154.         {
  155.         loop=ExAll(dir,(struct ExAllData *)buffer,4096,ED_COMMENT,eac);
  156.         if(!loop&&IoErr()!=ERROR_NO_MORE_ENTRIES)
  157.         {
  158.             error=RETURN_ERROR;
  159.             break;
  160.         }
  161.         if(eac->eac_Entries)
  162.         {
  163.             ead=(struct ExAllData *)buffer;
  164.             do
  165.             {
  166.             if (!AddEntry (ead->ed_Type > 0 ? &dirs : &files, ead->ed_Name))
  167.             {
  168.                 loop = 0;
  169.                 error=RETURN_ERROR;
  170.                 VPrintf ("out of memory\n", NULL);
  171.                 break;
  172.             }
  173.  
  174.             ead=ead->ed_Next;
  175.             }while(ead!=NULL);
  176.         }
  177.         }while(loop);
  178.         FreeDosObject(DOS_EXALLCONTROL,eac);
  179.  
  180.         if (!error)
  181.         {
  182.         if (dirs.num)
  183.         {
  184.             char * ptr;
  185.             int added_slash = 0;
  186.  
  187.             indent ++;
  188.  
  189.             qsort (dirs.entries, dirs.num, sizeof (char *),
  190.             compare_strings);
  191.  
  192.             ptr = path + strlen (path);
  193.  
  194.             if (*path && ptr[-1] != ':' && ptr[-1] != '/')
  195.             {
  196.             *ptr ++ = '/';
  197.             *ptr = 0;
  198.  
  199.             added_slash = 1;
  200.             }
  201.  
  202.             for (t=0; t<dirs.num; t++)
  203.             {
  204.             argv[0] = (IPTR) dirs.entries[t];
  205.  
  206.             if (args.all)
  207.             {
  208.                 strcpy (ptr, dirs.entries[t]);
  209.  
  210.                 showline ("%-25.s <DIR>\n", argv);
  211.                 do_dir ();
  212.             }
  213.             else
  214.                 showline ("    %-25.s <DIR>\n", argv);
  215.             }
  216.  
  217.             if (added_slash)
  218.             ptr[-1] = 0;
  219.  
  220.             indent --;
  221.         }
  222.  
  223.         if (files.num)
  224.         {
  225.             qsort (files.entries, files.num, sizeof (char *),
  226.             compare_strings);
  227.  
  228.             for (t=0; t<files.num; t+=2)
  229.             {
  230.             argv[0] = (IPTR) (files.entries[t]);
  231.             argv[1] = (IPTR) (t+1 < files.num ? files.entries[t+1] : "");
  232.             if (args.all)
  233.                 showline ("    %-25.s %-25.s\n", argv);
  234.             else
  235.                 showline ("%-25.s %-25.s\n", argv);
  236.             }
  237.         }
  238.         }
  239.  
  240.         if (dirs.num)
  241.         {
  242.         for (t=0; t<dirs.num; t++)
  243.         {
  244.             FreeVec (dirs.entries[t]);
  245.         }
  246.  
  247.         if (dirs.entries)
  248.             FreeVec (dirs.entries);
  249.         }
  250.  
  251.         if (files.num)
  252.         {
  253.         for (t=0; t<files.num; t++)
  254.         {
  255.             FreeVec (files.entries[t]);
  256.         }
  257.  
  258.         if (files.entries)
  259.             FreeVec (files.entries);
  260.         }
  261.     }else
  262.     {
  263.         SetIoErr(ERROR_NO_FREE_STORE);
  264.         error=RETURN_ERROR;
  265.     }
  266.     UnLock(dir);
  267.     }
  268.  
  269.     return error;
  270. }
  271.  
  272. static LONG tinymain(void)
  273. {
  274.     struct RDArgs *rda;
  275.     LONG error=0;
  276.  
  277.     rda=ReadArgs("Dir,OPT/K,ALL/S",(IPTR *)&args,NULL);
  278.     if(rda!=NULL)
  279.     {
  280.     strcpy (path, args.dir!=NULL?args.dir:"");
  281.  
  282.     error = do_dir ();
  283.  
  284.     FreeArgs(rda);
  285.     }else
  286.     error=RETURN_FAIL;
  287.     if(error)
  288.     PrintFault(IoErr(),"List");
  289.     return error;
  290. }
  291.  
  292. #ifdef NO_LINK
  293. #include "strcpy.c"
  294. #include "strlen.c"
  295. #include "qsort.c"
  296. #endif
  297.